package com.jeffse.light.stream.core.data.context;

import com.jeffse.light.stream.core.data.descriptor.operatorDescriptor.OperatorDescriptor;
import com.jeffse.light.stream.core.function.advance.FlatMapFunction;
import com.jeffse.light.stream.core.function.advance.MapFunction;
import com.jeffse.light.stream.core.function.advance.SlideWindowFunction;
import com.jeffse.light.stream.core.function.advance.WindowFunction;
import com.jeffse.light.stream.core.function.base.AbstractProcessFunction;
import com.jeffse.light.stream.core.function.base.WaterMarkFunction;
import com.jeffse.light.stream.core.pojo.OutTag;
import com.jeffse.light.stream.core.selector.KeyedSelector;

import java.io.Serializable;

public interface OperatorContext<KEY, T, V> extends Serializable {
    public enum WindowType
    {
        TIME, COUNT;
    }

    public enum SlideType
    {
        TIME, COUNT;
    }

    public enum UnitType
    {
        COUNT, SECONDS;
    }

    /**
     * 数据处理的函数
     * @param value
     * @return
     */
    public OperatorContext processElement(Object value, OperatorDescriptor operatorDescriptor) throws Exception;

    /**
     * 添加 window 过程函数
     * @return
     */
    public OperatorContext process(AbstractProcessFunction abstractProcessFunction) throws Exception;

    /**
     * 添加 window 过程函数
     * @return
     */
    public OperatorContext process(WindowFunction windowFunction) throws Exception;

    /**
     * 添加 SlideWindowFunction 过程函数
     * @return
     */
    public OperatorContext process(SlideWindowFunction slideWindowFunction) throws Exception;

    /**
     * 添加输出
     * @param mapFunction
     * @return
     */
    public OperatorContext map(MapFunction mapFunction);


    /**
     * 添加输出
     * @param flatMapFunction
     * @return
     */
    public OperatorContext flatMap(FlatMapFunction flatMapFunction);

    /**
     * keyedBy
     * @param keyedSelector
     * @return
     */
    public OperatorContext keyedBy(KeyedSelector<T, KEY> keyedSelector);

    /**
     * 设置水印
     */
    public OperatorContext setWaterMark(WaterMarkFunction<T> waterMarkFunction);

    /**
     * 合并数据流
     * @param outTag
     * @return
     */
    public OperatorContext union(OutTag outTag);

    /**
     * 窗口
     * @param windowType
     * @param num
     * @param unit
     * @return
     */
    public OperatorContext window(Enum<WindowType> windowType, Integer num, Enum<UnitType> unit, Boolean isEventTime) throws Exception;

    /**
     * 滑动窗口
     * @param windowType
     * @param x
     * @param unitX
     * @param y
     * @param unitY
     * @return
     */
    public OperatorContext slideWindow(Enum<WindowType> windowType, Integer x, Enum<UnitType> unitX, Integer y, Enum<UnitType> unitY, Boolean isEventTime) throws Exception;

    /**
     * 窗口数据统计
     * @return
     */
    public Integer count();

    /**
     * 窗口数据求平均值
     * @return
     */
    public Double avg();

    /**
     * 窗口数据求和
     * @return
     */
    public Double sum();

    /**
     * 窗口数据求最大值
     * @return
     */
    public Double max();

    /**
     * 窗口数据求最小值
     * @return
     */
    public Double min();
}
